package com.xuzz.xrpc.spring.context.processors;

import com.xuzz.xrpc.common.PropertyConfig;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.env.*;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @description:  replaced by {@link PropertyConfigAware}
 * @author: xuzz
 * @create: 2020-02-21 21:48
 */
@Deprecated
public class PropertiesBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, BeanFactoryAware, EnvironmentAware, Ordered {

    /**
     * 应用环境，用于获取配置属性
     */
    private StandardEnvironment environment;
    private BeanFactory beanFactory;

    public PropertiesBeanPostProcessor()
    {
        super();
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactoryToProcess) throws BeansException {
//        decryptProperty(propertyValues,valueResolver);
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        MutablePropertySources propertyValues =  environment.getPropertySources();

        Map<String,Object> xrpcProperties = new HashMap<>();
        propertyValues.forEach(pv->{
            PropertySource propertySource = propertyValues.get(pv.getName());
            if (propertySource instanceof MapPropertySource){
                //重新定义一个PropertySource，覆盖原来的
                String[] propertyNames = ((MapPropertySource) propertySource).getPropertyNames();
                for (int i=0,length = propertyNames.length;i<length;i++){
                    if(!propertyNames[i].startsWith("xrpc")){continue;}
                    xrpcProperties.put(propertyNames[i],propertySource.getProperty(propertyNames[i]));
                }
            }

        });
        registerPropertyConfigBean(registry,xrpcProperties);

    }

    private void registerPropertyConfigBean(BeanDefinitionRegistry registry,Map<String,Object> properties)
    {
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        //beanClass是一个FactoryBean的实现，那么在getObject的时候，会通过它
        beanDefinition.setBeanClass(PropertyConfig.class);
        beanDefinition.setLazyInit(false);

        String serverName = properties.get("xrpc.server.name").toString();
        if(!StringUtils.isEmpty(serverName))
        {
            beanDefinition.getPropertyValues().addPropertyValue("serverName",serverName);
        }

        //server address -> ip:port
        String serverAddress = properties.get("xrpc.server.address").toString();
        if(!StringUtils.isEmpty(serverAddress))
        {
            beanDefinition.getPropertyValues().addPropertyValue("serverAddress",serverAddress);
        }
        else
        {
            beanDefinition.getPropertyValues().addPropertyValue("serverAddress","127.0.0.1:12888");
        }

        //registry type ->
        String registryProtocol = properties.get("xrpc.registry.protocol").toString();
        if(!StringUtils.isEmpty(registryProtocol))
        {
            beanDefinition.getPropertyValues().addPropertyValue("registryProtocol",registryProtocol);
        }
        else
        {
            beanDefinition.getPropertyValues().addPropertyValue("registryProtocol","zookeeper");
        }

        //registry address -> ip:port
        String registryAddress = properties.get("xrpc.registry.address").toString();
        if(!StringUtils.isEmpty(registryAddress))
        {
            beanDefinition.getPropertyValues().addPropertyValue("registryAddress",registryAddress);
        }
        else
        {
            beanDefinition.getPropertyValues().addPropertyValue("registryAddress","127.0.0.1:2181");
        }

        String loadBalance = properties.get("xrpc.cluster.loadbalance").toString();
        if(!StringUtils.isEmpty(registryAddress))
        {
            beanDefinition.getPropertyValues().addPropertyValue("loadBalance",loadBalance);
        }
        else
        {
            beanDefinition.getPropertyValues().addPropertyValue("loadBalance","random");
        }

        registry.registerBeanDefinition("propertyConfig", beanDefinition);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public int getOrder() {
        return LOWEST_PRECEDENCE;
    }

    /**
     * 解密方法．遍历每个PropertySources，遍历PropertySources的每个键值如果包含加密信息就解密，最后替换．
     */
//    private void decryptProperty(MutablePropertySources propertyValues,EncryptStringValueResolver valueResolver) {
//        propertyValues.forEach(pv->{
//            PropertySource propertySource = propertyValues.get(pv.getName());
//            if (propertySource instanceof MapPropertySource){
//                //保存处理过后的值
//                Map<String,Object> convertPropertySource = new HashMap<>();
//                //重新定义一个PropertySource，覆盖原来的
//                MapPropertySource newMapPropertySource = new MapPropertySource(pv.getName(),convertPropertySource);
//                String[] propertyNames = ((MapPropertySource) propertySource).getPropertyNames();
//                for (int i=0,length = propertyNames.length;i<length;i++){
//                    Object value = propertySource.getProperty(propertyNames[i]);
//                    if (value instanceof String){
//                        convertPropertySource.put(propertyNames[i], valueResolver.resolveEncryptStringValue((String) value));
//                    }
//                    else {
//                        convertPropertySource.put(propertyNames[i],value);
//                    }
//                }
//                //处理过后值替换原来的PropertySource
//                propertyValues.replace(pv.getName(),newMapPropertySource);
//            }
//
//        });

//    }


    @Override
    public void setEnvironment(Environment environment) {
        this.environment = (StandardEnvironment)environment;
    }
}